package com.flydog.taskManager.dto;

import com.fasterxml.jackson.annotation.JsonValue;
import com.flydog.taskManager.common.util.DateUtil;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * 周期重复模式枚举
 *
 * @author caoweidong
 * @version 0.0.0
 * @create 2021/6/17 16:31
 */
public enum RepeatMode {
    /**
     * 每日
     */
    PRE_DAY(0, "preDay") {
        @Override
        public Calendar getPeriodEndTime(Calendar refreshTime, int settingNum) {
            return DateUtil.initDateToEndTimeInDay(refreshTime);
        }

        @Override
        public List<Calendar> getPeriodEndTimeList(Calendar endTime, int settingNum) {
            return new ArrayList<>();
        }
    },

    PRE_WEEK(1, "preWeek") {
        @Override
        public Calendar getPeriodEndTime(Calendar refreshTime, int settingNum) {
            Calendar currentWeekPeriodEndTime = DateUtil.initDateToStartTimeInDay(Calendar.getInstance());
            currentWeekPeriodEndTime.setFirstDayOfWeek(Calendar.MONDAY);
            currentWeekPeriodEndTime.set(Calendar.DAY_OF_WEEK, settingNum + 1);
            if (!refreshTime.before(currentWeekPeriodEndTime)) {
                int nextWeek = currentWeekPeriodEndTime.get(Calendar.WEEK_OF_YEAR) + 1;
                currentWeekPeriodEndTime.set(Calendar.WEEK_OF_YEAR, nextWeek);
            }
            return DateUtil.initDateToEndTimeInDay(currentWeekPeriodEndTime);
        }

        @Override
        public List<Calendar> getPeriodEndTimeList(Calendar endTime, int settingNum) {
            /*List<Calendar> endTimeList = new ArrayList<>();
            Calendar periodEndTime = getPeriodEndTime(Calendar.getInstance(), settingNum);
            while (periodEndTime.before(endTime)) {
                Calendar instance = Calendar.getInstance();
                instance.setTime(periodEndTime.getTime());
                endTimeList.add(instance);
                periodEndTime.add(Calendar.WEEK_OF_YEAR, 1);
            }
            return endTimeList;*/
            return new ArrayList<>();
        }
    },
    PRE_MONTH(2, "preMonth") {
        @Override
        public Calendar getPeriodEndTime(Calendar refreshTime, int settingNum) {
            Calendar currentMonthPeriodEndTime = DateUtil.initDateToStartTimeInDay(Calendar.getInstance());
            currentMonthPeriodEndTime.set(Calendar.DATE, settingNum);
            if (currentMonthPeriodEndTime.before(refreshTime)) {
                currentMonthPeriodEndTime.add(Calendar.MONTH, 1);
            }
            return DateUtil.initDateToEndTimeInDay(currentMonthPeriodEndTime);
        }

        @Override
        public List<Calendar> getPeriodEndTimeList(Calendar endTime, int settingNum) {
            /*List<Calendar> endTimeList = new ArrayList<>();
            Calendar periodEndTime = getPeriodEndTime(Calendar.getInstance(), settingNum);
            while (periodEndTime.before(endTime)) {
                Calendar instance = Calendar.getInstance();
                instance.setTime(periodEndTime.getTime());
                endTimeList.add(instance);
                periodEndTime.add(Calendar.MONTH, 1);
            }
            return endTimeList;*/
            return new ArrayList<>();
        }
    },
    PRE_QUARTER(3, "preQuarter") {
        @Override
        public Calendar getPeriodEndTime(Calendar refreshTime, int settingNum) {
            Calendar currentQuarterPeriodEndTime = DateUtil.initDateToStartTimeInDay(Calendar.getInstance());
            int currentQuarterBeginMonth = Math.floorDiv(currentQuarterPeriodEndTime.get(Calendar.MONTH), 3) * 3;
            currentQuarterPeriodEndTime.set(Calendar.MONTH, currentQuarterBeginMonth);
            currentQuarterPeriodEndTime.set(Calendar.DAY_OF_MONTH, 1);
            currentQuarterPeriodEndTime.add(Calendar.DAY_OF_YEAR, settingNum - 1);
            if (currentQuarterPeriodEndTime.before(refreshTime)) {
                currentQuarterPeriodEndTime.set(Calendar.MONTH, currentQuarterBeginMonth + 3);
            }
            return DateUtil.initDateToEndTimeInDay(currentQuarterPeriodEndTime);
        }

        @Override
        public List<Calendar> getPeriodEndTimeList(Calendar endTime, int settingNum) {
            List<Calendar> endTimeList = new ArrayList<>();
            Calendar periodEndTime = getPeriodEndTime(Calendar.getInstance(), settingNum);
            while (periodEndTime.before(endTime)) {
                Calendar instance = Calendar.getInstance();
                instance.setTime(periodEndTime.getTime());
                endTimeList.add(instance);
                periodEndTime.add(Calendar.MONTH, 3);
            }
            return endTimeList;
        }
    },
    PRE_HALF_YEAR(4, "preHalfYear") {
        @Override
        public Calendar getPeriodEndTime(Calendar refreshTime, int settingNum) {
            Calendar currentHalfYearPeriodEndTime = DateUtil.initDateToStartTimeInDay(Calendar.getInstance());
            int currentMonth = currentHalfYearPeriodEndTime.get(Calendar.MONTH);
            int beginMonth = currentMonth < 5 ? 0 : 5;
            currentHalfYearPeriodEndTime.set(Calendar.MONTH, beginMonth);
            currentHalfYearPeriodEndTime.set(Calendar.DAY_OF_MONTH, settingNum);
            if (currentHalfYearPeriodEndTime.before(refreshTime)) {
                currentHalfYearPeriodEndTime.add(Calendar.MONTH, 7);
            }
            return DateUtil.initDateToEndTimeInDay(currentHalfYearPeriodEndTime);
        }

        @Override
        public List<Calendar> getPeriodEndTimeList(Calendar endTime, int settingNum) {
            List<Calendar> endTimeList = new ArrayList<>();
            Calendar periodEndTime = getPeriodEndTime(Calendar.getInstance(), settingNum);
            while (periodEndTime.before(endTime)) {
                Calendar instance = Calendar.getInstance();
                instance.setTime(periodEndTime.getTime());
                endTimeList.add(instance);
                periodEndTime.add(Calendar.MONTH, 6);
            }
            return endTimeList;
        }
    },
    PRE_YEAR(5, "preYear") {
        @Override
        public Calendar getPeriodEndTime(Calendar refreshTime, int settingNum) {
            Calendar currentYearPeriodEndTime = DateUtil.initDateToStartTimeInDay(Calendar.getInstance());
            currentYearPeriodEndTime.set(Calendar.DAY_OF_YEAR, settingNum);
            if (currentYearPeriodEndTime.before(refreshTime)) {
                currentYearPeriodEndTime.add(Calendar.YEAR, 1);
            }
            return DateUtil.initDateToEndTimeInDay(currentYearPeriodEndTime);
        }

        @Override
        public List<Calendar> getPeriodEndTimeList(Calendar endTime, int settingNum) {
            List<Calendar> endTimeList = new ArrayList<>();
            Calendar periodEndTime = getPeriodEndTime(Calendar.getInstance(), settingNum);
            while (periodEndTime.before(endTime)) {
                Calendar instance = Calendar.getInstance();
                instance.setTime(periodEndTime.getTime());
                endTimeList.add(instance);
                periodEndTime.add(Calendar.YEAR, 1);
            }
            return endTimeList;
        }
    };


    private final int index;
    private final String name;

    RepeatMode(int index, String name) {
        this.index = index;
        this.name = name;
    }

    @JsonValue
    public int getIndex() {
        return index;
    }

    public String getName() {
        return name;
    }

    public abstract Calendar getPeriodEndTime(Calendar refreshTime, int settingNum);

    public abstract List<Calendar> getPeriodEndTimeList(Calendar endTime, int settingNum);


}
